/*
 * movements.h
 *
 *  Created on: Dec 17, 2011
 *      Author: armandoperico
 */

#include <algorithm>
#include "collisions.h"
#ifndef MOVEMENTS_H_
#define MOVEMENTS_H_


const float GRAVITY = 0.0f;
//The amount of time between each time that we handle collisions and apply the
//effects of gravity
const float TIME_BETWEEN_UPDATES = 0.001f;
const int TIMER_MS = 25; //The number of milliseconds to which the timer is set


//Moves all of the Cells by their velocity times dt
void moveCells(vector<Cell*> &cells, Octree* octree, float dt) {
	for(unsigned int i = 0; i < cells.size(); i++) {
		Cell* cell = cells[i];
		Vec3f oldPos = cell->pos;
		cell->pos += cell->v * dt;
		octree->CellMoved(cell, oldPos);
	}
}

//Decreases the y coordinate of the velocity of each Cell by GRAVITY *
void applyGravity(vector<Cell*> &cells) {
	for(unsigned int i = 0; i < cells.size(); i++) {
		Cell* cell = cells[i];
		cell->v -= Vec3f(0, GRAVITY * TIME_BETWEEN_UPDATES, 0);
	}
}


bool compare_cells(Cell* a,Cell* b){
	return a->r > b->r;
}


//Applies gravity and handles all collisions.  Should be called every TIME_BETWEEN_UPDATES seconds.
void performUpdate(vector<Cell*> &cells, Cell* mainCell,  Octree* octree) {
	sort(cells.begin(),cells.end(), compare_cells);
	applyGravity(cells);
	handleCellCellCollisions(cells, mainCell,  octree);
}

//Advances the state of the Cells by t.  timeUntilUpdate is the amount of time
//until the next call to performUpdate.
void advance(vector<Cell*> &cells, Cell * mainCell, Octree* octree, float t, float &timeUntilUpdate) {
	while (t > 0) {
		if (timeUntilUpdate <= t) {
			moveCells(cells, octree, timeUntilUpdate);
			performUpdate(cells, mainCell, octree);
			t -= timeUntilUpdate;
			timeUntilUpdate = TIME_BETWEEN_UPDATES;
		}
		else {
			moveCells(cells, octree, t);
			timeUntilUpdate -= t;
			t = 0;
		}
	}
}


#endif /* MOVEMENTS_H_ */
